﻿namespace DCHealthCheck {

    #region Usings
    using DCHealthCheck.Common;
    using DCHealthCheck.DomainModel;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Management;
    using System.Text; 
    #endregion

    public class ServiceInfoBuilder {

        #region Members
        private readonly ServiceInfo ServiceInfo;

        private readonly ManagementObject WmiObject; 
        #endregion

        #region Constructors
        private ServiceInfoBuilder() {
        }

        public ServiceInfoBuilder(ServiceInfo serviceInfo, ManagementObject wmiObject)
            : this() {
            if (serviceInfo == null) {
                throw new ArgumentNullException("serviceInfo");
            }
            if (wmiObject == null) {
                throw new ArgumentNullException("wmiObject");
            }

            this.ServiceInfo = serviceInfo;
            this.WmiObject = wmiObject;
        } 
        #endregion

        #region Methods
        public ServiceInfo GetServiceInfo() {
            if (WmiObject["DisplayName"] != null) this.ServiceInfo.DisplayName = WmiObject["DisplayName"].ToString();

            if (WmiObject["ErrorControl"] != null) {
                var serviceErrorControl = ServiceErrorControl.NotSpecified;
                if (Enum.TryParse<ServiceErrorControl>(WmiObject["ErrorControl"].ToString().Replace(" ", string.Empty), true, out serviceErrorControl)) {
                    this.ServiceInfo.ErrorControl = serviceErrorControl;
                }
            }


            if (WmiObject["ExitCode"] != null) this.ServiceInfo.ExitCode = ((WINERROR)Convert.ToUInt32(WmiObject["ExitCode"]));
            if (WmiObject["Name"] != null) this.ServiceInfo.Name = WmiObject["Name"].ToString();
            if (WmiObject["PathName"] != null) this.ServiceInfo.PathName = WmiObject["PathName"].ToString().Replace("\"", string.Empty);
            if (WmiObject["ProcessId"] != null) this.ServiceInfo.ProcessId = Convert.ToInt64(WmiObject["ProcessId"]);

            if (WmiObject["ServiceType"] != null) {
                var serviceType = ServiceType.NotSpecified;
                if (Enum.TryParse<ServiceType>(WmiObject["ServiceType"].ToString().Replace(" ", string.Empty), true, out serviceType)) {
                    this.ServiceInfo.ServiceType = serviceType;
                }
            }
            if (WmiObject["Started"] != null) this.ServiceInfo.Started = Convert.ToBoolean(WmiObject["Started"]);
            if (WmiObject["StartMode"] != null) {
                var serviceStartMode = ServiceStartMode.NotSpecified;
                if (Enum.TryParse<ServiceStartMode>(WmiObject["StartMode"].ToString().Replace(" ", string.Empty), true, out serviceStartMode)) {
                    this.ServiceInfo.StartMode = serviceStartMode;
                }
            }
            if (WmiObject["StartName"] != null) this.ServiceInfo.StartName = WmiObject["StartName"].ToString();
            if (WmiObject["State"] != null) {
                ServiceState serviceStateDescription = Common.ServiceState.NotSpecified;
                if (Enum.TryParse<ServiceState>(WmiObject["State"].ToString().Replace(" ", string.Empty), true, out serviceStateDescription)) {
                    this.ServiceInfo.State = serviceStateDescription;
                }
            }
            if (WmiObject["Status"] != null) {
                ServiceStatus serviceStatusDescription = Common.ServiceStatus.NotSpecified;
                if (Enum.TryParse<ServiceStatus>(WmiObject["Status"].ToString().Replace(" ", string.Empty), true, out serviceStatusDescription)) {
                    this.ServiceInfo.Status = serviceStatusDescription;
                }
            }

            return this.ServiceInfo;
        }

        public override string ToString() {
            if (this.ServiceInfo != null) {
                return this.ServiceInfo.ToString();
            }
            else {
                return string.Empty;
            }
        } 
        #endregion
    }
}
